from flask import Flask, request
from flask_cors import CORS
from flask.views import MethodView
from flask import jsonify
import jwt
from datetime import datetime, timedelta

from extension import db
from model import Job, UrgentJob, Role, User

from models import DAOFactory, Tutor, Score, Choice, Student, User2
server = 'localhost'
user ='sa'
password = '123456'
database = 'database-design'
charset='utf8mb4'

factory = DAOFactory(server, user, password, database)

app = Flask(__name__)
CORS().init_app(app)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///jobs.sqlite'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)
print('hello,world')

@app.cli.command()
def create():
    db.drop_all()
    db.create_all()
    Job.init_db()
    UrgentJob.init_db()
    Role.init_db()
    User.init_db()


@app.route('/')
def hello_campus_greening():
    student_dao = factory.getStudentDAO()
    all_students = student_dao.find_all()
    # return jsonify(all_students)
    return jsonify([student.__dict__ for student in all_students])
    # return 'Wel111come Campus_greening'
def verify_token():
    token = None
    if 'Authorization' in request.headers:
        auth_header = request.headers['Authorization']
        if auth_header.startswith('Bearer '):
            token = auth_header.split(' ')[1]
    if not token:
        return False
    try:
        jwt.decode(token, 'your_secret_key', algorithms=['HS256'])
        return True
    except jwt.ExpiredSignatureError:
        return False
    except jwt.InvalidTokenError:
        return False

# class StudentApi(MethodView):
#     def get(self):
#         if verify_token():
#             # jobs: [Job] = Job.query.all()
#             student_dao = factory.getStudentDAO()
#             all_students = student_dao.find_all()
#             # return jsonify(all_students)
#             return jsonify([student.__dict__ for student in all_students])
#             # return {
#             #     'status': 'success',
#             #     'message': '数据查询成功',
#             #     'results': all_students
#             # }
#         else:
#             return {
#                 'token无效'
#             }

class JobApi(MethodView):
    def get(self, job_id):
        if verify_token():
            if not job_id:
                jobs: [Job] = Job.query.all()
                results = [
                    {
                        'id': job.id,
                        'job_people': job.job_people,
                        'job_content': job.job_content,
                        "job_last_date": job.job_last_date,
                        "job_important": job.job_important,
                        "job_delay": job.job_delay,
                        "job_delay_reason": job.job_delay_reason,
                    }for job in jobs
                ]
                return{
                    'status': 'success',
                    'message': '数据查询成功',
                    'results': results
                }
            job: Job = Job.query.get(job_id)
            return {
                'status': 'success',
                'message': '数据查询成功',
                'results': {
                    'id': job.id,
                    'job_people': job.job_people,
                    'job_content': job.job_content,
                    "job_last_date": job.job_last_date,
                    "job_important": job.job_important,
                    "job_delay": job.job_delay,
                    "job_delay_reason": job.job_delay_reason,
                }
            }
        else:
            return {
                'token无效'
            }

    def post(self):
        form = request.json
        job = Job()
        job.job_people = form.get('job_people')
        job.job_content = form.get('job_content')
        job.job_last_date = form.get('job_last_date')
        job.job_important = form.get('job_important')
        job.job_delay = form.get('job_delay')
        job.job_delay_reason = form.get('job_delay_reason')
        db.session.add(job)
        db.session.commit()

        return {
            'status': 'success',
            'message': '数据添加成功'
        }

    def delete(self, job_id):
        job: Job = Job.query.get(job_id)
        db.session.delete(job)
        db.session.commit()
        return {
            'status': 'success',
            'message': '数据删除成功'
        }

    def put(self, job_id):
        form = request.json
        job: Job = Job.query.get(job_id)
        job.id = form.get('id')
        job.job_people = form.get('job_people')
        job.job_content = form.get('job_content')
        job.job_last_date = form.get('job_last_date')
        job.job_important = form.get('job_important')
        job.job_delay = form.get('job_delay')
        job.job_delay_reason = form.get('job_delay_reason')
        db.session.add(job)
        db.session.commit()
        return {
            'status': 'success',
            'message': '数据修改成功'
        }

class UrgentJobApi(MethodView):
    def get(self, job_id):
        if not job_id:
            jobs: [Job] = UrgentJob.query.all()
            results = [
                {
                    'id': job.id,
                    'job_people': job.job_people,
                    'job_content': job.job_content,
                    "job_last_date": job.job_last_date
                }for job in jobs
            ]
            return{
                'status': 'success',
                'message': '数据查询成功',
                'results': results
            }
        job: Job = Job.query.get(job_id)
        return {
            'status': 'success',
            'message': '数据查询成功',
            'results': {
                'id': job.id,
                'job_people': job.job_people,
                'job_content': job.job_content,
                "job_last_date": job.job_last_date
            }
        }

    def post(self):
        form = request.json
        job = Job()
        job.job_people = form.get('job_people')
        job.job_content = form.get('job_content')
        job.job_last_date = form.get('job_last_date')
        db.session.add(job)
        db.session.commit()

        return {
            'status': 'success',
            'message': '数据添加成功'
        }

    def delete(self, job_id):
        job: Job = Job.query.get(job_id)
        db.session.delete(job)
        db.session.commit()
        return {
            'status': 'success',
            'message': '数据删除成功'
        }

    def put(self, job_id):
        form = request.json
        job: Job = Job.query.get(job_id)
        job.id = form.get('id')
        job.job_people = form.get('job_people')
        job.job_content = form.get('job_content')
        job.job_last_date = form.get('job_last_date')
        db.session.add(job)
        db.session.commit()
        return {
            'status': 'success',
            'message': '数据修改成功'
        }

def login():
    form = request.json
    user_id = form.get('username')
    password = form.get('password')

    # user = User2(username, password)
    userDao = factory.getUserDao()
    user: User2 = userDao.find_by_id(user_id)
    print(user)
    # user: User = User.query.filter_by(user_name=username).first()
    if user and user.password == password:
        payload = {
            'user_id': user.id,
            'exp': datetime.utcnow() + timedelta(hours=1)
        }
        token = jwt.encode(payload, 'your_secret_key', algorithm='HS256')
        role_id = userDao.get_role(user.id)
        return {
            'id': user.id,
            'role_id': role_id,
            'user_name': user.user_name,
            'password': user.password,
            'token': token,
            'status': 'success'
        }
    else:
        return {
            'status': 'failed'
        }

class UserApi(MethodView):
    def get(self):
        if verify_token():
            users = User.query.all()
            user_list = [{'id': user.id, 'user_name': user.user_name, 'user_password': user.user_password, 'role_id': user.role_id} for user in users]
            return user_list
        else:
            return 'token无效'

    def post(self):
        if verify_token():
            form = request.json
            user = User()
            user.user_name = form.get('user_name')
            user.user_password = form.get('user_password')
            user.role_id = form.get('role_id')
            db.session.add(user)
            db.session.commit()

            return {
                'status': 'success',
                'message': '用户添加成功'
            }
        else:
            return  'token无效'

    def delete(self, user_id):
        if verify_token():
            user: User = User.query.get(user_id)
            db.session.delete(user)
            db.session.commit()
            return {
                'status': 'success',
                'message': '数据删除成功'
            }
        else:
            return 'token无效'

    def put(self, user_id):
        if verify_token():
            form = request.json
            user: User = User.query.get(user_id)
            user.user_name = form.get('user_name')
            user.user_password = form.get('user_password')
            user.role_id = form.get('role_id')
            db.session.add(user)
            db.session.commit()
            return {
                'status': 'success',
                'message': '数据修改成功'
            }
        else:
            return 'token无效'

@app.route('/subjects', methods=['GET'])
def get_subjects():
    if verify_token():
        primary_subject_dao = factory.getPrimarySubjectDAO()
        primary_subjects = primary_subject_dao.find_all()

        secondary_suject_dao = factory.getSecondarySubjectDAO()
        secondary_subjects = secondary_suject_dao.find_all()

        result_array = []
        for primary_subject in primary_subjects:
            primary_info = {
                'id': primary_subject.id,
                'name': primary_subject.name,
                'description': primary_subject.description,
                'total_num': primary_subject.total_num,
                'supply_num': primary_subject.supply_num,
                'type': primary_subject.type,
                'secondary_subjects': []
            }
            for secondary_subject in secondary_subjects:
                if secondary_subject['parent_id'] == primary_subject.id:
                    primary_info['secondary_subjects'].append({
                        'id': secondary_subject['id'],
                        'name': secondary_subject['name'],
                        'description': secondary_subject['description'],
                        'initial_subject1': secondary_subject['initial_subject1'],
                        'initial_subject2': secondary_subject['initial_subject2'],
                        'initial_subject3': secondary_subject['initial_subject3'],
                        'initial_subject4': secondary_subject['initial_subject4'],
                        'interview_subject1': secondary_subject['interview_subject1'],
                        'interview_subject2': secondary_subject['interview_subject2'],
                        'tutors': secondary_subject['tutors']
                    })
            result_array.append(primary_info)
        return jsonify(result_array)

class StudentApi(MethodView):
    def get(self, student_id):
        if verify_token():
            if not student_id:
                student_dao = factory.getStudentDAO()
                students = student_dao.find_all()

                result_array = []
                for student in students:
                    student_info = {
                        'id': student.id,
                        'name': student.name,
                        'birth': student.birth,
                        'idnumber': student.idnumber,
                        'birth_place': student.birth_place,
                        'undergraduate_major': student.undergraduate_major,
                        'email': student.email,
                        'phone': student.phone,
                        'undergraduate_institution': student.undergraduate_institution,
                        'institution_type': student.institution_type,
                        'gender': student.gender,
                        'resume': student.resume,
                        'subject_id': student.subject_id,
                        'subject_name': student.subject_name
                    }
                    result_array.append(student_info)
                return jsonify(result_array)
            else:
                student_dao = factory.getStudentDAO()
                students = student_dao.find_by_id(student_id)
                result_array = []
                for student in students:
                    student_info = {
                        'id': student.id,
                        'name': student.name,
                        'birth': student.birth,
                        'idnumber': student.idnumber,
                        'birth_place': student.birth_place,
                        'undergraduate_major': student.undergraduate_major,
                        'email': student.email,
                        'phone': student.phone,
                        'undergraduate_institution': student.undergraduate_institution,
                        'institution_type': student.institution_type,
                        'gender': student.gender,
                        'resume': student.resume,
                        'subject_id': student.subject_id,
                        'subject_name': student.subject_name
                    }
                    result_array.append(student_info)
                return jsonify(result_array)

    def put(self, student_id):
        if verify_token():
            form = request.json
            print(form)
            student = Student(form['id'], form['name'], form['birth'], form['idnumber'], form['birth_place'],
                              form['undergraduate_major'],
                              form['email'], form['phone'], form['undergraduate_institution'], form['institution_type'],
                              form['gender'],
                              form['resume'], form['subject_id'], form['subject_name'])
            student_dao = factory.getStudentDAO()
            student_dao.update(student)
            return {
                'status': 'success',
                'message': '数据修改成功'
            }

class TutorApi(MethodView):
    def get(self, tutor_id):
        if verify_token():
            if tutor_id:
                tutor_dao = factory.getTutorDAO()
                tutors = tutor_dao.find_by_id(tutor_id)
                result_array = []
                for tutor in tutors:
                    tutor_info = {
                        'id': tutor.id,
                        'name': tutor.name,
                        'title': tutor.title,
                        'photo': tutor.photo,
                        'introduction': tutor.introduction,
                        'email': tutor.email,
                        'phone': tutor.phone,
                        'eligibility': tutor.eligibility
                    }
                    result_array.append(tutor_info)
                return jsonify(result_array)
            else:
                tutor_dao = factory.getTutorDAO()
                tutors = tutor_dao.find_all()
                result_array = []
                for tutor in tutors:
                    tutor_info = {
                        'id': tutor.id,
                        'name': tutor.name,
                        'title': tutor.title,
                        'photo': tutor.photo,
                        'introduction': tutor.introduction,
                        'email': tutor.email,
                        'phone': tutor.phone,
                        'eligibility': tutor.eligibility
                    }
                    result_array.append(tutor_info)
                return jsonify(result_array)

    def put(self, tutor_id):
        if verify_token():
            form = request.json
            tutor = Tutor(form['id'], form['name'], form['title'], form['photo'], form['introduction'], form['email'], form['phone'], form['eligibility'])
            tutor_dao = factory.getTutorDAO()
            tutor_dao.update(tutor)
            return {
                'status': 'success',
                'message': '数据修改成功'
            }


class ChoiceApi(MethodView):
    def get(self, student_id):
        if verify_token():
            if not student_id:
                choiceDao = factory.getChoiceDAO()
                choices = choiceDao.find_all()
                result_array = []
                for choice in choices:
                    choice_info = {
                        'id': choice.id,
                        'student_id': choice.student_id,
                        'student_name': choice.student_name,
                        'first_choice_instructor': choice.first_choice_instructor,
                        'first_choice_instructor_name': choice.first_choice_instructor_name,
                        'second_choice_instructor': choice.second_choice_instructor,
                        'second_choice_instructor_name': choice.second_choice_instructor_name,
                        'third_choice_instructor': choice.third_choice_instructor,
                        'third_choice_instructor_name': choice.third_choice_instructor_name
                    }
                    result_array.append(choice_info)
                return jsonify(result_array)
            else:
                choiceDao = factory.getChoiceDAO()
                choices = choiceDao.find_by_id(student_id)
                result_array = []
                for choice in choices:
                    choice_info = {
                        'id': choice.id,
                        'student_id': choice.student_id,
                        'student_name': choice.student_name,
                        'first_choice_instructor': choice.first_choice_instructor,
                        'first_choice_instructor_name': choice.first_choice_instructor_name,
                        'second_choice_instructor': choice.second_choice_instructor,
                        'second_choice_instructor_name': choice.second_choice_instructor_name,
                        'third_choice_instructor': choice.third_choice_instructor,
                        'third_choice_instructor_name': choice.third_choice_instructor_name
                    }
                    result_array.append(choice_info)
                return jsonify(result_array)
    def put(self, choice_id):
        if verify_token():
            form = request.json
            choice = Choice(form['id'], form['student_id'], form['student_name'], form['first_choice_instructor'], form['first_choice_instructor_name'],
                            form['second_choice_instructor'], form['second_choice_instructor_name'], form['third_choice_instructor'], form['third_choice_instructor_name']
                            )
            choiceDao = factory.getChoiceDAO()
            choiceDao.update(choice)
            return {
                'status': 'success',
                'message': '数据修改成功'
            }

@app.route('/find_tutor/<int:tutor_id>', methods=['GET'])
def get_choice_tutor(tutor_id):
    # if verify_token():
        choiceDao = factory.getChoiceDAO()
        results = choiceDao.find_tutor(tutor_id)
        return jsonify(results)


@app.route('/get_tutors/<int:student_id>', methods=['GET'])
def get_tutors(student_id):

    tutorDao = factory.getTutorDAO()
    results = tutorDao.get_tutors(student_id)
    return jsonify(results)

class ScoreApi(MethodView):
    def get(self, student_id):
        if verify_token():
            if not student_id:
                scoreDao = factory.getScoreDAO()
                scores = scoreDao.find_all()
                result_array = []
                for score in scores:
                    choice_info = {
                        'id': score.id,
                        'student_id': score.student_id,
                        'initial_score1': score.initial_score1,
                        'initial_score2': score.initial_score2,
                        'initial_score3': score.initial_score3,
                        'initial_score4': score.initial_score4,
                        'interview_subject1': score.interview_subject1,
                        'interview_subject2': score.interview_subject2
                    }
                    result_array.append(choice_info)
                return jsonify(result_array)
            else:
                scoreDao = factory.getScoreDAO()
                scores = scoreDao.find_by_id(student_id)
                result_array = []
                for score in scores:
                    choice_info = {
                        'id': score.id,
                        'student_id': score.student_id,
                        'initial_score1': score.initial_score1,
                        'initial_score2': score.initial_score2,
                        'initial_score3': score.initial_score3,
                        'initial_score4': score.initial_score4,
                        'interview_subject1': score.interview_subject1,
                        'interview_subject2': score.interview_subject2
                    }
                    result_array.append(choice_info)
                return jsonify(result_array)

    def put(self, score_id):
        if verify_token():
            form = request.json
            print(form)
            score = Score(form['id'], form['student_id'], form['initial_score1'], form['initial_score2'], form['initial_score3'],
                          form['initial_score4'], form['interview_subject1'], form['interview_subject2'])

            score_dao = factory.getScoreDAO()
            score_dao.update(score)
            return {
                'status': 'success',
                'message': '数据修改成功'
            }


job_api = JobApi.as_view('job_api')
app.add_url_rule('/jobs', view_func=job_api, methods=['GET', ], defaults={'job_id': None})
app.add_url_rule('/jobs', view_func=job_api, methods=['POST', ])
app.add_url_rule('/jobs/<int:job_id>', view_func=job_api, methods=['GET', 'PUT', 'DELETE'])


urgent_job_api = UrgentJobApi.as_view('urgent_job_api')
app.add_url_rule('/urgent_jobs', view_func=urgent_job_api, methods=['GET', ], defaults={'job_id': None})
app.add_url_rule('/urgent_jobs', view_func=urgent_job_api, methods=['POST', ])
app.add_url_rule('/jobs/<int:job_id>', view_func=urgent_job_api, methods=['GET', 'PUT', 'DELETE'])


app.add_url_rule('/login', view_func=login, methods=['POST'])


user_api = UserApi.as_view('user_api')
app.add_url_rule('/users', view_func=user_api, methods=['GET', ])
app.add_url_rule('/users', view_func=user_api, methods=['POST', ])
app.add_url_rule('/users/<int:user_id>', view_func=user_api, methods=['PUT', 'DELETE'])

tutor_api = TutorApi.as_view('tutor_api')
app.add_url_rule('/tutors', view_func=tutor_api, methods=['GET'], defaults={'tutor_id': None})
app.add_url_rule('/tutors/<int:tutor_id>', view_func=tutor_api, methods=['GET'])
app.add_url_rule('/tutors/<int:tutor_id>', view_func=tutor_api, methods=['PUT'])

score_api = ScoreApi.as_view('score_api')
app.add_url_rule('/scores', view_func=score_api, methods=['GET'], defaults={'student_id': None})
app.add_url_rule('/scores/<int:student_id>', view_func=score_api, methods=['GET'])
app.add_url_rule('/scores/<int:score_id>', view_func=score_api, methods=['PUT'])

choice_api = ChoiceApi.as_view('choice_api')
app.add_url_rule('/choices', view_func=choice_api, methods=['GET'], defaults={'student_id': None})
app.add_url_rule('/choices/<int:student_id>', view_func=choice_api, methods=['GET'])
app.add_url_rule('/choices/<int:choice_id>', view_func=choice_api, methods=['PUT'])


student_api = StudentApi.as_view('student_api')
app.add_url_rule('/students', view_func=student_api, methods=['GET'], defaults={'student_id': None})
app.add_url_rule('/students/<int:student_id>', view_func=student_api, methods=['GET'])
app.add_url_rule('/students/<int:student_id>', view_func=student_api, methods=['PUT'])